package com.example.fireassistant_server.service.impl;

import com.example.fireassistant_server.dto.PointSearchFilter;
import com.example.fireassistant_server.dto.circle.CircleCreateRequest;
import com.example.fireassistant_server.dto.circle.CircleDto;
import com.example.fireassistant_server.dto.circle.CircleUpdateRequest;
import com.example.fireassistant_server.entity.*;
import com.example.fireassistant_server.exception.BizException;
import com.example.fireassistant_server.exception.ExceptionType;
import com.example.fireassistant_server.mapper.CircleMapper;
import com.example.fireassistant_server.repository.CircleRepository;
import com.example.fireassistant_server.repository.spec.CircleSpecification;
import com.example.fireassistant_server.repository.spec.PointSearchCriteria;
import com.example.fireassistant_server.repository.spec.SearchOperation;
import com.example.fireassistant_server.service.CircleService;
import com.example.fireassistant_server.service.FileService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class CircleServiceImpl implements CircleService {

    private CircleRepository circleRepository;

    private CircleMapper circleMapper;

    private FileService fileService;

    @Override
    @Transactional
    public CircleDto addCircle(CircleCreateRequest circleCreateRequest, User user) {
        //制作circle
        Circle circle = circleMapper.createEntity(circleCreateRequest);
        //存储中心点
        circle.setUserId(user.getId());
        return circleMapper.toDto(circleRepository.save(circle));
    }

    @Override
    public CircleDto get(String id) {
        Optional<Circle> circle = circleRepository.findById(id);
        if (!circle.isPresent()) {
            throw new BizException(ExceptionType.CIRCLE_NOT_FOUND);
        }
        return circleMapper.toDto(circle.get());
    }

    @Override
    @Transactional
    public void delete(String id) {
        Optional<Circle> circle = circleRepository.findById(id);
        if (!circle.isPresent()) {
            throw new BizException(ExceptionType.CIRCLE_NOT_FOUND);
        }
        circleRepository.deleteById(id);

        // 先删除对应的file
        List<File> files=circle.get().getFiles();
        if (!files.isEmpty()){
            files.forEach(item->{
                fileService.delete("circle",item.getId());
            });
        }

    }

    @Override
    public Page<CircleDto> search(PointSearchFilter pointSearchFilter) {
        CircleSpecification specs = new CircleSpecification();
        //添加所查询的latitude范围
        if (!Objects.equals(pointSearchFilter.getMinLatitude(), null) && !Objects.equals(pointSearchFilter.getMaxLatitude(), null)) {
            specs.add(new PointSearchCriteria("latitude", pointSearchFilter.getMinLatitude(), pointSearchFilter.getMaxLatitude(), SearchOperation.BETWEEN));
        }
        //添加所查询的longitude范围
        if (!Objects.equals(pointSearchFilter.getMinLongitude(), null) && !Objects.equals(pointSearchFilter.getMaxLongitude(), null)){
            specs.add(new PointSearchCriteria("longitude", pointSearchFilter.getMinLongitude(), pointSearchFilter.getMaxLongitude(), SearchOperation.BETWEEN));
        }
        return circleRepository.findAll(specs, pointSearchFilter.toPageable()).map(circleMapper::toDto);
    }

    @Override
    public CircleDto update(String id, CircleUpdateRequest circleUpdateRequest) {
        Optional<Circle> circle = circleRepository.findById(id);
        if (!circle.isPresent()) {
            throw new BizException(ExceptionType.CIRCLE_NOT_FOUND);
        }

        if (circleUpdateRequest.getLatitude()!= null){
            circle.get().setLatitude(circleUpdateRequest.getLatitude());
        }

        if (circleUpdateRequest.getBackground_color()!= null){
            circle.get().setBackground_color(circleUpdateRequest.getBackground_color());
        }

        if (circleUpdateRequest.getLongitude()!= null){
            circle.get().setLongitude(circleUpdateRequest.getLongitude());
        }

        if (circleUpdateRequest.getRadius()!=0.0){
            circle.get().setRadius(circleUpdateRequest.getRadius());
        }

        if (circleUpdateRequest.getDescription()!= null){
            circle.get().setDescription(circleUpdateRequest.getDescription());
        }

        circleRepository.flush();
        return circleMapper.toDto(circleRepository.save(circle.get()));

    }


    @Autowired
    public void setCircleRepository(CircleRepository circleRepository) {
        this.circleRepository = circleRepository;
    }

    @Autowired
    public void setCircleMapper(CircleMapper circleMapper) {
        this.circleMapper = circleMapper;
    }


    @Autowired
    public void setFileService(FileService fileService) {
        this.fileService = fileService;
    }
}
